import { matchingList, updateMatching, updateOrder } from '@/services/ant-design-pro/matching';
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import {
  ModalForm,
  PageContainer,
  ProFormText,
  ProFormUploadButton,
  ProTable,
} from '@ant-design/pro-components';
import { message } from 'antd';
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';

import { EditOutlined, HolderOutlined } from '@ant-design/icons';
import type { DragEndEvent } from '@dnd-kit/core';
import { DndContext } from '@dnd-kit/core';
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { Button } from 'antd';

interface RowContextProps {
  setActivatorNodeRef?: (element: HTMLElement | null) => void;
  listeners?: SyntheticListenerMap;
}

const RowContext = React.createContext<RowContextProps>({});
const DragHandle: React.FC = () => {
  const { setActivatorNodeRef, listeners } = useContext(RowContext);
  return (
    <Button
      type="text"
      size="small"
      icon={<HolderOutlined />}
      style={{ cursor: 'move' }}
      ref={setActivatorNodeRef}
      {...listeners}
    />
  );
};

interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
  'data-row-key': string;
}

const Row: React.FC<RowProps> = (props) => {
  const {
    attributes,
    listeners,
    setNodeRef,
    setActivatorNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: props['data-row-key'] });

  const style: React.CSSProperties = {
    ...props.style,
    transform: CSS.Translate.toString(transform),
    transition,
    ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}),
  };

  const contextValue = useMemo<RowContextProps>(
    () => ({ setActivatorNodeRef, listeners }),
    [setActivatorNodeRef, listeners],
  );

  return (
    <RowContext.Provider value={contextValue}>
      <tr {...props} ref={setNodeRef} style={style} {...attributes} />
    </RowContext.Provider>
  );
};

interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {
  'data-row-key': string;
}

const TableList: React.FC = () => {
  // 修改窗口的弹窗
  const [updateModalOpen, handleUpdateModalOpen] = useState<boolean>(false);
  //选择的修改数据
  const [selectUpdateInfo, setSelectUpdateInfo] = useState<API.MatchingItem>();
  //引用
  const actionRef = useRef<ActionType>();

  const [dataSource, setDataSource] = useState<API.MatchingItem[] | any>([]);
  /**
   * 数据
   */
  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      let matching: API.MatchingList = await matchingList({ current: 1, pageSize: 50 });
      if (matching?.success) {
        setDataSource(matching?.data);
      }
    } catch (error) {
      console.error('加载失败！错误：', error);
    }
  };

  //排序
  const onDragEnd = async ({ active, over }: DragEndEvent) => {
    if (active.id !== over?.id) {
      const hide = message.loading('正在修改');
      try {
        await updateOrder(active.id, over?.id)
          .then(() => {
            if (actionRef.current) {
              actionRef.current.reload();
              fetchData();
            }
          })
          .catch((e) => {
            throw new Error('修改顺序失败' + e);
          });
        hide();

        message.success('修改成功');
        return true;
      } catch (error) {
        hide();
        return false;
      }
    }
  };
  /**
     表格
    */

  const columns: ProColumns<API.MatchingItem>[] = [
    {
      key: 'sort',
      align: 'center',
      width: 80,
      search: false,
      render: () => <DragHandle />,
    },
    {
      title: '组件名称',
      dataIndex: 'componentName',
      key: 'componentName',
    },
    {
      title: '匹配词（以，分隔）',
      dataIndex: 'matching',
      key: 'matching',
    },
  ];
  columns.push({
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    search: false,
    width: 200,
    render: (text, record: API.MatchingItem) => (
      <div>
        <Button
          type="link"
          icon={<EditOutlined />}
          onClick={() => {
            handleUpdateModalOpen(true);
            setSelectUpdateInfo(record);
          }}
        >
          修改
        </Button>
      </div>
    ),
  });

  /**
   * @en-US Update node
   * @zh-CN 更新节点
   *
   * @param fields
   */

  const handleUpdate = async (fields: any) => {
    const hide = message.loading('正在修改');
    try {
      await updateMatching({
        selectUpdateInfo,
        ...fields,
      });
      hide();

      message.success('修改成功');
      return true;
    } catch (error) {
      hide();
      message.error('修改失败, 新增失败，请稍后重试！!');
      return false;
    }
  };

  return (
    <PageContainer>
      {/* 表格 */}
      <DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>
        <SortableContext
          items={dataSource.map((e: API.MatchingItem) => e.key)}
          strategy={verticalListSortingStrategy}
        >
          <ProTable<API.MatchingItem, API.PageParams>
            headerTitle={'匹配词管理'}
            actionRef={actionRef}
            rowKey="key"
            search={{
              labelWidth: 120,
            }}
            pagination={{ pageSize: 20 }}
            components={{
              body: {
                row: Row,
              },
            }}
            request={matchingList}
            columns={columns}
            // dataSource={dataSource}
          />
        </SortableContext>
      </DndContext>
      {/* 修改弹窗 */}
      <ModalForm
        title={'修改'}
        width="400px"
        open={updateModalOpen}
        initialValues={selectUpdateInfo}
        onOpenChange={handleUpdateModalOpen}
        onFinish={async (value) => {
          const success = await handleUpdate(value as API.MatchingItem);
          if (success) {
            handleUpdateModalOpen(false);
            if (actionRef.current) {
              actionRef.current.reload();
            }
          }
        }}
      >
        <ProFormText
          name="componentName"
          label="组件名称"
          disabled={true}
        />
        <ProFormText
          name="matching"
          label="匹配词（以，分隔）"
          rules={[{ required: true, message: '请输入匹配词' }]}
        />
      </ModalForm>
    </PageContainer>
  );
};

export default TableList;
